import 'package:flutter/material.dart';

import '../../config/public_text.dart';
import '../../model/key_value_model.dart';
import '../../tool/public_tool.dart';
import '../divider/public_divider.dart';
import '../gesture/hide_keyboard_gesture.dart';
import '../header/action_sheet_header.dart';
import '../search/model/search_result_model.dart';
import '../search/search_view.dart';

/// FileName modal_bottom_sheet
///
/// @Author lax
/// @Date 2023/5/17
///
/// @Description

class ModalBottomSheet {
  /// 显示底部弹窗 高度由child决定
  static Future<dynamic> show({
    required BuildContext context,
    Color? color = Colors.white,
    bool enableDrag = true,
    bool isDismissible = true,
    double? radius = 16,
    double? height,
    double? heightRatio,
    Widget? child,
  }) async {
    FocusScope.of(context).requestFocus(FocusNode());
    return await showModalBottomSheet(
      isScrollControlled: true,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(radius ?? 0),
          topRight: Radius.circular(radius ?? 0),
        ),
      ),
      backgroundColor: color,
      enableDrag: enableDrag,
      isDismissible: isDismissible,
      context: context,
      builder: (context) {
        return SizedBox(
            height: height ??
                (heightRatio == null
                    ? null
                    : MediaQuery.of(context).size.height * heightRatio),
            child: child);
      },
    );
  }

  /// 带关闭按钮的弹窗
  static Future<dynamic> showCloseSheet({
    required BuildContext context,
    Color? color = Colors.white,
    bool enableDrag = true,
    bool isDismissible = true,
    double? radius = 16,
    double? height,
    double heightRatio = 0.5,
    Widget? child,
    String? title,
    TextStyle? titleStyle,
    bool showDivider = false,
    int? titleMaxLines = 1,
  }) async {
    return await ModalBottomSheet.show(
      context: context,
      color: color,
      enableDrag: enableDrag,
      isDismissible: isDismissible,
      radius: radius,
      height: height,
      heightRatio: heightRatio,
      child: Column(
        children: [
          ActionSheetHeader(
            title: title,
            titleStyle: titleStyle,
            maxLines: titleMaxLines,
            onClose: () {
              Navigator.pop(context);
            },
          ),
          Visibility(
            visible: showDivider,
            child: const PublicDivider(),
          ),
          Expanded(child: child ?? const SizedBox()),
        ],
      ),
    );
  }

  /// 带确认按钮的弹窗
  static Future<dynamic> showConfirmSheet({
    required BuildContext context,
    Color? color = Colors.white,
    bool enableDrag = true,
    bool isDismissible = true,
    double? radius = 16,
    double? height,
    double heightRatio = 0.5,
    Widget? child,
    bool showDivider = false,
    bool hideKeyboard = false,
    String? title,
    TextStyle? titleStyle,
    String? cancelText,
    String? confirmText,
    TextStyle? cancelTextStyle,
    TextStyle? confirmTextStyle,
    Function()? onConfirm, // 可通过返回false控制弹窗不自动关闭
    int? titleMaxLines = 1,
  }) async {
    return await ModalBottomSheet.show(
      context: context,
      color: color,
      enableDrag: enableDrag,
      isDismissible: isDismissible,
      radius: radius,
      height: height,
      heightRatio: heightRatio,
      child: HideKeyboardGesture(
        needHide: hideKeyboard,
        child: Column(
          children: [
            ActionSheetHeader(
              title: title,
              titleStyle: titleStyle,
              maxLines: titleMaxLines,
              cancelText: cancelText,
              confirmText: confirmText,
              cancelTextStyle: cancelTextStyle,
              confirmTextStyle: confirmTextStyle,
              onCancel: () {
                Navigator.pop(context);
              },
              onConfirm: () async {
                dynamic result = await onConfirm?.call();
                if (!context.mounted) {
                  return;
                }
                if (result == null) {
                  Navigator.pop(context);
                } else {
                  if (result != false) {
                    Navigator.pop(context, result);
                  }
                }
              },
            ),
            Visibility(
              visible: showDivider,
              child: const PublicDivider(),
            ),
            Expanded(child: child ?? const SizedBox()),
          ],
        ),
      ),
    );
  }

  /// 单选弹窗
  static Future<KeyValueModel?> showSingleSheet({
    required BuildContext context,
    String? title,
    TextStyle? titleStyle,
    String? cancelText,
    String? confirmText,
    TextStyle? cancelTextStyle,
    TextStyle? confirmTextStyle,
    String? selectedId,
    List<KeyValueModel>? dataSource,
    SearchViewItemCallback? onSelectedItem,
    Function(KeyValueModel? value)? onConfirm,
    bool? isShowSearchBar,
    int heightChangeDataSourceCount = 5,
    int showSearchBarDataSourceCount = 10,
  }) async {
    return await showActionSheet(
      context: context,
      title: title,
      titleStyle: titleStyle,
      cancelText: cancelText,
      confirmText: confirmText,
      cancelTextStyle: cancelTextStyle,
      confirmTextStyle: confirmTextStyle,
      selectedId: selectedId,
      dataSource: dataSource,
      onSelectedItem: onSelectedItem,
      onConfirm: onConfirm,
      showSearchBar: isShowSearchBar,
      heightChangeDataSourceCount: heightChangeDataSourceCount,
      showSearchBarDataSourceCount: showSearchBarDataSourceCount,
    );
  }

  /// 多选弹窗
  static Future<SearchResultModel> showMultipleSheet({
    required BuildContext context,
    String? title,
    TextStyle? titleStyle,
    String? cancelText,
    String? confirmText,
    TextStyle? cancelTextStyle,
    TextStyle? confirmTextStyle,
    String? selectedId,
    List<KeyValueModel>? dataSource,
    Function(SearchResultModel value)? onConfirm,
    bool? isShowSearchBar,
    int heightChangeDataSourceCount = 5,
    int showSearchBarDataSourceCount = 10,
  }) async {
    final result = await showActionSheet(
      context: context,
      multiSelect: true,
      title: title,
      titleStyle: titleStyle,
      cancelText: cancelText,
      confirmText: confirmText,
      cancelTextStyle: cancelTextStyle,
      confirmTextStyle: confirmTextStyle,
      selectedId: selectedId,
      dataSource: dataSource,
      onConfirm: onConfirm,
      showSearchBar: isShowSearchBar,
      heightChangeDataSourceCount: heightChangeDataSourceCount,
      showSearchBarDataSourceCount: showSearchBarDataSourceCount,
    );
    if (result == null) {
      return SearchResultModel();
    }
    return result;
  }

  /// 单选/多选弹窗
  static Future<dynamic> showActionSheet({
    required BuildContext context,
    bool multiSelect = false,
    bool showDivider = false,
    String? title,
    TextStyle? titleStyle,
    String? cancelText,
    String? confirmText,
    TextStyle? cancelTextStyle,
    TextStyle? confirmTextStyle,
    String? selectedId,
    List<KeyValueModel>? dataSource,
    String? searchButtonText, // 搜索框右侧按钮
    Function? onConfirm, // 可通过返回false控制弹窗不自动关闭
    SearchViewItemCallback? onSelectedItem,
    SearchViewButtonCallback? onPressedSearchButton,
    bool? showSearchBar,
    int heightChangeDataSourceCount = 5,
    int showSearchBarDataSourceCount = 10,
    int? titleMaxLines = 1,
  }) async {
    GlobalKey<SearchViewState> searchKey = GlobalKey();
    bool high = listGetLength(dataSource) > heightChangeDataSourceCount;
    bool isShowSearchBar = showSearchBar ??
        (listGetLength(dataSource) > showSearchBarDataSourceCount);
    final value = await ModalBottomSheet.show(
      context: context,
      isDismissible: !isShowSearchBar,
      color: Colors.white,
      height: high
          ? MediaQuery.of(context).size.height / 3 * 2
          : MediaQuery.of(context).size.height / 2,
      child: HideKeyboardGesture(
        needHide: isShowSearchBar,
        child: Column(
          children: [
            ActionSheetHeader(
              title: title ?? PublicText.pleaseSelect,
              titleStyle: titleStyle,
              maxLines: titleMaxLines,
              onCancel: () {
                Navigator.pop(context);
              },
              onConfirm: () async {
                final value = searchKey.currentState?.getSelectData();
                dynamic result;
                bool? canClose;
                if (multiSelect) {
                  result = value;
                  canClose = await onConfirm?.call(value);
                } else {
                  if (listIsEmpty(value?.selectedList)) {
                    canClose = await onConfirm?.call(null);
                  } else {
                    result = value?.selectedList?.first;
                    canClose =
                        await onConfirm?.call(value?.selectedList?.first);
                  }
                }
                if (canClose != false && context.mounted) {
                  Navigator.pop(context, result);
                }
              },
            ),
            Visibility(
              visible: showDivider,
              child: const PublicDivider(),
            ),
            Expanded(
              child: SearchView(
                key: searchKey,
                title: title,
                selectedId: selectedId,
                dataSource: dataSource ?? [],
                multiSelect: multiSelect,
                showSearchBar: isShowSearchBar,
                searchButtonText: searchButtonText,
                onSelectedItem: onSelectedItem,
                onPressedSearchButton: onPressedSearchButton,
              ),
            ),
          ],
        ),
      ),
    );
    return value;
  }
}
